package com.succez.server.servlet;

import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
import com.succez.server.servlet.http.WebApp;
import com.succez.server.utils.CloseUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Response {

    /**
     * 构建404、403、500等错误的html模板
     */
    private String str1 = "<!DOCTYPE html><html lang='en'><head><meta charset='UTF-8'><meta name='viewport' content='width=device-width, initial-scale=1.0'><title>";

    private String str2 = "</title></head><body><div id='head'style='width:100%;height:35px;background-color: #525D76;font-size: larger;color: aliceblue;font-weight: bold;line-height: 35px;'>";

    private String str3 = "</div><hr><div id='content' style='width:100%;'><span style='background-color: #525D76;'>类型:</span>&nbsp;";

    private String str4 = "<br /><br /><span style='background-color: #525D76;'>消息:</span>&nbsp;";

    private String str5 = "<br /><br /><span style='background-color: #525D76;'>描述:</span>&nbsp;";

    private String str6 = "<br /></div><hr></body></html>";

    private final static Logger logger = LoggerFactory.getLogger(Response.class);

    /**
     * 状态码
     */
    private int code;

    /**
     * 发生Internal Error时的堆栈信息
     */
    private String failText;

    /**
     * 状态行，如HTTP/1.1 200
     */
    private StringBuffer statusLine;

    /**
     * 原始头部信息（为防止多次设置相同头部）
     */
    private Map<String, String> rawHeadInfo;

    /**
     * 实际头部信息
     */
    private StringBuffer headInfo;

    /**
     * 主体信息
     */
    private StringBuffer bodyText;

    /**
     * 该连接对应socket，初始化后就不能修改
     */
    private final Socket socket;

    public void close() {
        if (this.socket != null) {
            CloseUtil.closeSocket(socket);
        }
    }

    public OutputStream getOutputStream() {
        try {
            return socket.getOutputStream();
        } catch (IOException e) {
            logger.error("获取socket输出流异常");
        }
        return null;
    }

    private PrintWriter getPrintWriter() {
        return new PrintWriter(new OutputStreamWriter(getOutputStream()));
    }

    public void pushToClient() {
        // 清空原来的headInfo
        headInfo.delete(0, headInfo.length());
        parseRawHeadInfo();
        StringBuffer responseText = new StringBuffer();
        responseText.append(statusLine.toString());
        responseText.append(headInfo.toString());
        int len = 0;
        len = bodyText.toString().getBytes().length;
        responseText.append("content-length:" + len).append(Consts.CRLF);
        responseText.append(Consts.CRLF);
        responseText.append(bodyText.toString());
        PrintWriter printWriter = getPrintWriter();
        printWriter.println(responseText.toString());
        printWriter.flush();
        CloseUtil.colseIo(printWriter);
    }

    /**
     * 将rawHeadInfo转换为字符串
     */
    private void parseRawHeadInfo() {
        for (String key : rawHeadInfo.keySet()) {
            /**
             * 禁止用户操纵content-length,在实际输出设置
             */
            if (!"content-length".equals(key)) {
                headInfo.append(key + ":" + rawHeadInfo.get(key)).append(Consts.CRLF);
            }
        }
    }

    /**
     * 子类负责建立状态码对应关系
     * 
     * @param code
     */
    public void setStatusLine(int code) {
        this.statusLine.delete(0, statusLine.length());
        this.code = 0;
        this.code = code;
        String statusText = WebApp.statusCodeMappings.get(code);
        statusLine.append("HTTP/1.1").append(" ").append(code).append(" ").append(statusText).append(Consts.CRLF);
    };

    /**
     * 调用一次添加一个头部
     * 
     * @param headKey
     * @param headValue
     */
    public void setHeadInfo(String headKey, String headValue) {
        rawHeadInfo.put(headKey, headValue);
    };

    /**
     * 
     * @param text 具体的内容
     */
    public void setBodyText(String text) {
        bodyText.delete(0, bodyText.length());
        bodyText.append(text);
    };

    public Response(Socket socket) {
        this.socket = socket;
        failText = "";
        statusLine = new StringBuffer();
        rawHeadInfo = new HashMap<>();
        headInfo = new StringBuffer();
        bodyText = new StringBuffer();
    }

    public String getFailText() {
        return failText;
    }

    public void setFailText(String failText) {
        this.failText = failText;
    }

    /**
     * 产生404、403、500等错误页面
     * 
     * @param title     文本标题
     * @param htmlTitle html浏览器栏标题
     * @param errorCat  类型
     * @param message   消息
     * @param text      描述
     * @return
     */
    public String generateError(String title, String htmlTitle, String errorCat, String message, String text) {
        StringBuffer bodyText = new StringBuffer();
        bodyText.append(str1).append(htmlTitle).append(str2).append(title).append(str3).append(errorCat).append(str4)
                .append(message).append(str5).append(text).append(str6);
        return bodyText.toString();
    }

    public StringBuffer getStatusLine() {
        return statusLine;
    }

    public int getCode() {
        return code;
    }

}